home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
BASE64.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-18
|
4KB
|
177 lines
#include "config.h"
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: base64.c,v 1.8 1997/01/18 16:13:20 root Exp root $";
#endif
#if defined(HTTP) || defined(BROWSER) || defined(TEST)
char *strToBase64 (char *str);
char *base64ToStr (char *b64);
static int findBase64 (char c);
extern void *mallocw (unsigned nb);
#define NULLCHAR ((char *)0)
static char lkBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int
findBase64 (c)
char c;
{
int k;
for (k = 0; k < 64; k++)
if (lkBase64[k] == c)
return k;
return -1;
}
/* returns a malloc'ed string which is the original string converted to
base64, or NULLCHAR if cannot malloc, per RFC 1521 */
char *
strToBase64 (char *thestr)
{
char *b64, *out;
unsigned char *str = (unsigned char *)thestr;
int multiple, remainder, len;
int val;
len = (int) strlen((char *)str);
multiple = len / 3;
remainder = len % 3;
out = b64 = mallocw ((unsigned int)(((multiple + 1) * 4) + 1));
if (out == NULLCHAR)
return out;
while (multiple--) {
out[0] = lkBase64[(str[0] >> 2) & 0x3f];
val = (str[1] >> 4) & 0x0f;
out[1] = lkBase64[val | ((str[0] << 4) & 0x30)];
val = (str[1] << 2) & 0x3c;
out[2] = lkBase64[val | ((str[2] >> 6) & 3)];
out[3] = lkBase64[str[2] & 0x3f];
out += 4;
str += 3;
}
out[0] = 0;
if (remainder != 0) {
out[0] = lkBase64[(str[0] >> 2) & 0x3f];
out[1] = out[2] = out[3] = '=';
out[4] = 0;
if (remainder == 2) {
val = (str[1] >> 4) & 0x0f;
out[1] = lkBase64[val | ((str[0] << 4) & 0x30)];
out[2] = lkBase64[(str[1] << 2) & 0x3c];
} else {
out[1] = lkBase64[(str[0] << 4) & 0x30];
}
}
return (b64);
}
/* returns a malloc'ed string which is the original string converted from
base64, per RFC 1521 - Returns a NULLCHAR if invalid characters
found or memory cannot be allocated, otherwise the memory must
STILL be freed. */
char *
base64ToStr (char *b64)
{
char *str, *out;
int multiple, remainder = 0, pad = 0, len;
int val, temp;
len = (int) strlen ((char *)b64);
multiple = len / 4;
if (b64[len - 1] == '=')
pad++;
if (b64[len - 2] == '=')
pad++;
switch (pad) {
case 2: remainder = 1;
break;
case 1: remainder = 2;
break;
case 0:
default: break;
}
if (pad)
multiple--;
out = str = mallocw ((unsigned int)((multiple * 3) + 1));
if (out == NULLCHAR)
return out;
while (multiple--) {
if ((temp = findBase64 (b64[0])) == -1)
goto error;
val = (temp << 2); /*lint !e701 */
if ((temp = findBase64 (b64[1])) == -1)
goto error;
out[0] = val | ((temp >> 4) & 3); /*lint !e702 !e734 */
val = (temp & 0x0f) << 4;
if ((temp = findBase64 (b64[2])) == -1)
goto error;
out[1] = val | ((temp >> 2) & 0x0f); /*lint !e702 !e734 */
out[2] = (temp << 6); /*lint !e701 !e734 */
if ((temp = findBase64 (b64[3])) == -1)
goto error;
out[2] |= temp; /*lint !e734 */
out += 3;
b64 += 4;
}
out[0] = 0;
if (remainder != 0) {
if ((temp = findBase64 (b64[0])) == -1)
goto error;
val = (temp << 2); /*lint !e701 */
if ((temp = findBase64 (b64[1])) == -1)
goto error;
out[0] = val | ((temp >> 4) & 3); /*lint !e702 !e734 */
out[1] = 0;
if (remainder == 2) {
if ((temp = findBase64 (b64[1])) == -1)
goto error;
val = (temp & 0x0f) << 4;
if ((temp = findBase64 (b64[2])) == -1)
goto error;
out[1] = val | ((temp >> 2) & 0x0f); /*lint !e702 !e734 */
out[2] = 0;
}
}
return (str);
error:
str[0] = 0; /*lint !e613 */
return (str);
}
#ifdef TEST
void
main (argc, argv)
int argc;
char *argv[];
{
if (argc != 3)
exit (0);
if (argv[1][0] == 't')
printf ("Encoding '%s': '%s'\n", argv[2], strToBase64 ((unsigned char *)argv[2]));
else
printf ("Decoding '%s': '%s'\n", argv[2], base64ToStr ((unsigned char *)argv[2]));
}
#endif /* TEST */
#endif /* HTTP */